//
//  NativeMediaPickerHelper.m
//  NativeMediaPicker
//
//  Created by Hai Trinh on 5/17/12.
//  Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//

#import "NativeMediaPickerHelper.h"

static  NSString *event_cancel_name = @"MEDIA_PICKER_EVENT_CANCELLED";
static  NSString *event_picked_name = @"MEDIA_PICKER_EVENT_PICKED";
static  NSString *event_update_playback_time_name = @"MEDIA_PICKER_EVENT_UPDATE_PLAYBACK_TIME";
static  NSString *event_playback_state_playing = @"MEDIA_PICKER_EVENT_PLAYBACK_STATE_PLAYING";
static  NSString *event_playback_state_paused = @"MEDIA_PICKER_EVENT_PLAYBACK_STATE_PAUSED";
static  NSString *event_playback_state_stopped = @"MEDIA_PICKER_EVENT_PLAYBACK_STATE_STOPPED";
static  NSString *event_playback_state_interruped = @"MEDIA_PICKER_EVENT_PLAYBACK_STATE_INTERRUPED";
static  NSString *event_playback_state_seeking_backward = @"MEDIA_PICKER_EVENT_PLAYBACK_STATE_SEEKING_BACKWARD";
static  NSString *event_playback_state_seeking_forward = @"MEDIA_PICKER_EVENT_PLAYBACK_STATE_SEEKING_FORWARD";
static  NSString *event_name = @"MEDIA_PICKER_EVENT";

#define PLAY_COMMAND @"play"
#define PAUSE_COMMAND @"pause"

@implementation NativeMediaPickerHelper

#pragma mark build json

/**
 *  build json contains information of the song, this json will be transfered to Flex.
 *  @param item instance of MPMediaItem, contain the information of playing song.
 *  @return string presents the json
 */
- (NSString*) buildJSON:(MPMediaItem *)item{
    NSString* title = [item valueForProperty:MPMediaItemPropertyTitle];
    NSURL* assetURL = [item valueForProperty:MPMediaItemPropertyAssetURL];
    NSString* extension = [TSLibraryImport extensionForAssetURL:assetURL];
    NSUInteger duration = [[item valueForProperty:MPMediaItemPropertyPlaybackDuration] intValue];
    return [NSString stringWithFormat:@"{\"title\":\"%@\",\"extension\":\"%@\",\"filePath\":\"%@\",\"model\":\"com.infrared5.model::Song\",\"duration\":\"%d\"}",title,extension,[assetURL absoluteString],duration];
}

#pragma mark open media picker

/**
 *  open the media picker to pick song.
 */
- (void)showMediaPicker{
    MPMediaPickerController* mediaPicker = [[MPMediaPickerController alloc] initWithMediaTypes:MPMediaTypeAnyAudio] ;
    mediaPicker.delegate = self;
    [[[[UIApplication sharedApplication] keyWindow] rootViewController] presentModalViewController:mediaPicker animated:YES];
    [mediaPicker release];
}

/**
 * set FREContext
 */

-(void)setContext:(FREContext)ctx {
    context = ctx;
}

#pragma mark - song controller

/** 
 * Called from Flex, seek the playing song
 * @param playbackTime seek the playing song to this time
 */
- (void)seek:(NSUInteger) playbackTime{
    appMusicPlayer = [MPMusicPlayerController applicationMusicPlayer];
    if (!appMusicPlayer) {
        return;
    }
    appMusicPlayer.currentPlaybackTime = playbackTime;
}

/**
 * Called from Flex to play/pause song
 * @param command command to play/pause song
 */
- (void)playSong:(NSString*)command{
    appMusicPlayer = [MPMusicPlayerController applicationMusicPlayer];
    if (!appMusicPlayer) {
        return;
    }
    if ([command isEqualToString:PLAY_COMMAND]) {
        [appMusicPlayer play];
    }else if([command isEqualToString:PAUSE_COMMAND]){
        [appMusicPlayer pause];
    }
}

/**
 * Timer to track the current progress of playing song, dispatch an event to Flex
 */
- (void) updatePlayingFrame{
    appMusicPlayer = [MPMusicPlayerController applicationMusicPlayer];
    if (appMusicPlayer.playbackState == MPMusicPlaybackStatePlaying) {
        NSString *currentPlayBackTime = [NSString stringWithFormat:@"%d",(int)appMusicPlayer.currentPlaybackTime];
        FREDispatchStatusEventAsync(context, (uint8_t*)[event_update_playback_time_name UTF8String], (uint8_t*)[currentPlayBackTime UTF8String]);
    }
}

/**
 *  Receive the change of state of playing song
 */
- (void) nowPlayingitemChange:(id)sender{
    appMusicPlayer = [MPMusicPlayerController applicationMusicPlayer];
    if (appMusicPlayer.playbackState == MPMusicPlaybackStatePaused) {
        FREDispatchStatusEventAsync(context, (uint8_t*)[event_playback_state_paused UTF8String],(uint8_t*)[@"null" UTF8String]);
    }else if (appMusicPlayer.playbackState == MPMusicPlaybackStatePlaying) {
        FREDispatchStatusEventAsync(context, (uint8_t*)[event_playback_state_playing UTF8String],(uint8_t*)[@"null" UTF8String]);
    }else if (appMusicPlayer.playbackState == MPMusicPlaybackStateInterrupted) {
        FREDispatchStatusEventAsync(context, (uint8_t*)[event_playback_state_interruped UTF8String],(uint8_t*)[@"null" UTF8String]);
    }else if (appMusicPlayer.playbackState == MPMusicPlaybackStateSeekingBackward) {
        FREDispatchStatusEventAsync(context, (uint8_t*)[event_playback_state_seeking_backward UTF8String],(uint8_t*)[@"null" UTF8String]);
    }else if (appMusicPlayer.playbackState == MPMusicPlaybackStateSeekingForward) {
        FREDispatchStatusEventAsync(context, (uint8_t*)[event_playback_state_seeking_forward UTF8String],(uint8_t*)[@"null" UTF8String]);
    }else if (appMusicPlayer.playbackState == MPMusicPlaybackStateStopped) {
        FREDispatchStatusEventAsync(context, (uint8_t*)[event_playback_state_stopped UTF8String],(uint8_t*)[@"null" UTF8String]);
    }
}

#pragma mark - MPMediaPickerController delegate

/**
 *  Close the media picker
 */ 
- (void) mediaPickerDidCancel:(MPMediaPickerController *)mediaPicker{

    FREDispatchStatusEventAsync(context, (uint8_t*)[event_cancel_name UTF8String], (uint8_t*)[event_cancel_name UTF8String]);
	    
    //hide media picker
    [[[[UIApplication sharedApplication] keyWindow] rootViewController] dismissModalViewControllerAnimated:YES];
}

/**
 *  pick song to play here
 */
- (void) mediaPicker:(MPMediaPickerController *)mediaPicker didPickMediaItems:(MPMediaItemCollection *)mediaItemCollection{
        
	appMusicPlayer = [MPMusicPlayerController applicationMusicPlayer];
    [appMusicPlayer setQueueWithItemCollection:mediaItemCollection];
    
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(nowPlayingitemChange:) name:MPMusicPlayerControllerPlaybackStateDidChangeNotification object:nil];
    [appMusicPlayer beginGeneratingPlaybackNotifications];
    [appMusicPlayer play];

    if (timer) {
        [timer invalidate];
        timer =  nil;
    }
    
    timer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(updatePlayingFrame) userInfo:nil repeats:YES];
    
    MPMediaItem *item = appMusicPlayer.nowPlayingItem;
    NSString *musicInformationJson = [self buildJSON:item];
    FREDispatchStatusEventAsync(context, (uint8_t*)[event_picked_name UTF8String], (uint8_t*)[musicInformationJson UTF8String]);
    
    //hide media picker
    [[[[UIApplication sharedApplication] keyWindow] rootViewController] dismissModalViewControllerAnimated:YES];
}

#pragma mark memory management

- (void)dealloc{
    if (timer) {
        [timer invalidate];
        timer =  nil;
    }
    [appMusicPlayer endGeneratingPlaybackNotifications];
    [[NSNotificationCenter defaultCenter] removeObserver:self name:MPMusicPlayerControllerPlaybackStateDidChangeNotification object:nil];
    [super dealloc];
}

@end
